/*
 * WxUtils.cpp
 *
 *  Created on: Sep 7, 2011
 *      Author: erudhes
 */
#include <wx/socket.h>
#include "WxUtils.h"

DEFINE_EVENT_TYPE(WXTASK_EVENT);
IMPLEMENT_DYNAMIC_CLASS(WxUtils::TaskEvent, wxEvent)
BEGIN_EVENT_TABLE(WxUtils::TaskScheduler, wxEvtHandler)
EVT_TASK_EVENT(WxUtils::TaskScheduler::onScheduleTask)
END_EVENT_TABLE()

const WxUtils::Color WxUtils::RED(255, 0, 0);
const WxUtils::Color WxUtils::GREEN(0, 255, 0);
const WxUtils::Color WxUtils::BLUE(0, 0, 255);
const WxUtils::Color WxUtils::BLACK(0, 0, 0);
const WxUtils::Color WxUtils::WHITE(255, 255, 255);
const wxPoint WxUtils::INVALID_POINT(-1, -1);

/**
 * WxUtils::ITask interface
 */

WxUtils::ITask::ITask()
{
	// Nothing to do yet
}

WxUtils::ITask::~ITask()
{
	// Nothing to do yet
}

/**
 * WxUtils::TaskEvent class
 */

WxUtils::TaskEvent::TaskEvent(WxUtils::ITask* task): mTask(task)
{
	this->m_eventType = WXTASK_EVENT;
}

WxUtils::TaskEvent::TaskEvent(const WxUtils::TaskEvent& taskEvent): mTask(taskEvent.mTask)
{
	this->m_eventType = taskEvent.m_eventType;
}

/*virtual*/
WxUtils::TaskEvent::~TaskEvent()
{
	// Nothing to do yet
}

wxEvent* WxUtils::TaskEvent::Clone() const
{
	return new TaskEvent(*this);
}

/**
 * WxUtils::TaskScheduler class
 */

/*static*/
void WxUtils::TaskScheduler::schedule(WxUtils::ITask* task)
{
	static TaskScheduler taskScheduler;
	TaskEvent taskEvent(task);

	taskScheduler.AddPendingEvent(taskEvent);
}

WxUtils::TaskScheduler::TaskScheduler()
{
	// Nothing to do
}

WxUtils::TaskScheduler::~TaskScheduler()
{
	// Nothing to do
}

void WxUtils::TaskScheduler::onScheduleTask(wxEvent& event)
{
	TaskEvent& taskEvent = static_cast<TaskEvent&>(event);
	ITask* task = taskEvent.getTask();

	task->execute();
	delete task;
	taskEvent.resetTask();
}

/**
 * WxUtils::Color class
 */

WxUtils::Color::Color(): mRed(0), mGreen(0), mBlue(0)
{
	// Nothing to do
}

WxUtils::Color::Color(unsigned char red, unsigned char green, unsigned char blue): mRed(red), mGreen(green), mBlue(blue)
{
	// Nothing to do
}

std::vector<wxPoint> WxUtils::getPointsAround(const wxPoint& point, unsigned int radius)
{
	std::vector<wxPoint> result;

	// Reserve place for nine positions for possible later use of the vector
	result.reserve(9);
	result.push_back(wxPoint(point.x - radius, point.y));
	result.push_back(wxPoint(point.x + radius, point.y));
	result.push_back(wxPoint(point.x, point.y - radius));
	result.push_back(wxPoint(point.x, point.y + radius));
	result.push_back(wxPoint(point.x - radius, point.y + radius));
	result.push_back(wxPoint(point.x - radius, point.y - radius));
	result.push_back(wxPoint(point.x + radius, point.y - radius));
	result.push_back(wxPoint(point.x + radius, point.y + radius));

	return result;
}

WxUtils::SocketError WxUtils::getSocketError(wxSocketBase* socket, unsigned int size)
{
	unsigned int lastCount = 0;

	wxASSERT_MSG(NULL != socket, wxT("The given socket is NULL!!!"));
	lastCount = socket->LastCount();
	if(lastCount != size || true == socket->Error())
	{
		if(0 == socket->LastCount())
			return DISCONNECTION;
		else
			return IO_ERROR;
	}

	return NONE;
}

wxString WxUtils::getLocalIpAddress()
{
	static wxString localIpAddress;

	if(wxT("") == localIpAddress)
	{
		wxIPV4address remote;
		wxIPV4address local;
		wxSocketClient client;

		// Try to connect to a remote public host and get out local address
		// This method was found on the internet
		remote.Hostname(wxT("www.wxwidgets.org"));
		remote.Service(80);
		if(client.Connect(remote))
		{
			client.GetLocal(local);
			localIpAddress = local.IPAddress();
		}
	}

	return localIpAddress;
}

WxUtils::WxUtils()
{
	// Nothing to do
}

WxUtils::~WxUtils()
{
	// Nothing to do
}

